package com.talkweb.platform.commonapi.query;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.talkweb.platform.commonapi.utils.ResourceUtil;

import io.swagger.annotations.ApiModelProperty;

/**
 * 表示一个查询条件<br>
 * 所有查询条件的字段名<b>fieldName</b>都是不区分大小写的
 * 
 * @author lzy
 * @version [版本号, 2017年5月11日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class QueryCondition implements Serializable {

	/**
	 * <属性变量说明>
	 * 
	 */
	private static final long serialVersionUID = -7497360506430086257L;

	@ApiModelProperty(value = "查询条件的字段名")
	private String fieldName;

	@ApiModelProperty(value = "查询条件的取值")
	private Object[] fieldValues;

	@ApiModelProperty(value = "与其他查询条件连接关系(逻辑与/逻辑或)")
	private Prepender prepender;

	/**
	 * 比较符号
	 */
	@ApiModelProperty(value = "比较符号")
	private Operator operator;

	@ApiModelProperty(value = "子查询条件列表")
	private List<QueryCondition> childCondtions;

	public QueryCondition(String fieldName, Prepender prepender, Operator operator, Object... fieldValues) {
		super();
		this.fieldName = fieldName;
		this.fieldValues = fieldValues;
		this.prepender = prepender;
		this.operator = operator;
	}

	public QueryCondition(String fieldName, Prepender prepender, Operator operator, Collection<?> fieldValues) {
		this(fieldName, prepender, operator,
				(null != fieldValues && !fieldValues.isEmpty()) ? fieldValues.toArray() : null);
	}

	public QueryCondition() {
		super();
		this.prepender = Prepender.AND;
	}

	public QueryCondition(Prepender prepender) {
		super();
		this.prepender = prepender;
	}

	public String getFieldName() {
		return fieldName;
	}

	public void setFieldName(String fieldName) {
		this.fieldName = fieldName;
	}

	public Prepender getPrepender() {
		return prepender;
	}

	public void setPrepender(Prepender prepender) {
		this.prepender = prepender;
	}

	public List<QueryCondition> getChildCondtions() {
		return childCondtions;
	}

	public void setChildCondtions(List<QueryCondition> childCondtions) {
		this.childCondtions = childCondtions;
	}

	public Object[] getFieldValues() {
		return fieldValues;
	}

	public void setFieldValues(Object[] fieldValues) {
		this.fieldValues = fieldValues;
	}

	public Operator getOperator() {
		return operator;
	}

	public void setOperator(Operator operator) {
		this.operator = operator;
	}

	/**
	 * 添加单个查询子对象
	 * 
	 * @param condition
	 *            [参数说明]
	 * @return
	 * 
	 * @see List#add(Object)
	 */
	public QueryCondition addChildCondition(QueryCondition condition) {
		if (this.childCondtions == null) {
			childCondtions = new ArrayList<QueryCondition>();
		}
		childCondtions.add(condition);
		return this;
	}

	/**
	 * 添加子查询对象
	 * 
	 * @param conditions
	 *            [参数说明]
	 * @return
	 * 
	 * @see List#addAll(Collection)
	 */
	public QueryCondition addChildConditionList(Collection<QueryCondition> conditions) {
		if (this.childCondtions == null) {
			childCondtions = new ArrayList<QueryCondition>();
		}
		childCondtions.addAll(conditions);
		return this;
	}

	/**
	 * 返回一个国际化的condition
	 * 
	 * @return [参数说明]
	 * 
	 * @return QueryCondition [返回类型说明]
	 * @exception throws
	 *                [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static QueryCondition getLanguageCondition() {
		return new QueryCondition("lang", Prepender.AND, Operator.EQUAL, ResourceUtil.getLocale());
	}

	/**
	 * 返回一个国际化的conditionList
	 * 
	 * @return [参数说明]
	 * 
	 * @return QueryCondition [返回类型说明]
	 * @exception throws
	 *                [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 */
	public static List<QueryCondition> getLangConditionList() {
		List<QueryCondition> list = new ArrayList<QueryCondition>();
		list.add(getLanguageCondition());
		return list;
	}

	/**
	 * 是否包含子对象
	 * 
	 * @return [参数说明]
	 * 
	 * @see CollectionUtils#isNotEmpty(Collection)
	 */
	public boolean hasChild() {
		return (null != childCondtions && !childCondtions.isEmpty());
	}

	/**
	 * 清除子条件
	 * 
	 * @return void [返回类型说明]
	 * @exception throws
	 *                [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 */
	public void clearChilds() {
		if (hasChild()) {
			childCondtions.clear();
		}
	}

	/**
	 * 比较符
	 */
	public enum Operator {
		GREATER_THAN(">"), LESS_THAN("<"), EQUAL("="), NOT_EQUAL("<>"), GREATER_EQUAL(">="), LESS_EQUAL(
				"<="), FUZZY_MATCH("LIKE"), NOT_FUZZY_MATCH(
						"NOT LIKE"), IN("IN"), NOT_IN("NOT IN"), IS_NULL("IS NULL"), IS_NOT_NULL("IS NOT NULL");

		private String value;

		private Operator(String value) {
			this.value = value;
		}

		public String value() {
			return this.value;
		}
	}

	/**
	 * 前置连接逻辑运算符
	 */
	public enum Prepender {
		/**
		 * AND
		 */
		AND("AND"),
		/**
		 * OR
		 */
		OR("OR");

		private String value;

		private Prepender(String value) {
			this.value = value;
		}

		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}
	}

}